<template>
  <div class="person-recognition">
    <div class="toolbar">
      <div class="left-actions">
        <button class="upload-btn" @click="triggerUpload" :disabled="loading">
          <i class="icon">📤</i>
          {{ loading ? '处理中...' : '上传图片' }}
        </button>
      </div>
      <div class="right-actions">
        <button class="export-btn" @click="exportDataset">
          <i class="icon">📦</i>
          导出数据集
        </button>
      </div>
      <input 
        type="file" 
        ref="fileInput"
        accept="image/*"
        multiple
        @change="handleFileSelect"
        style="display: none"
      >
    </div>

    <div class="content-area">
      <!-- 左侧图片列表 -->
      <div class="images-list">
        <div v-for="image in images" 
             :key="image.id" 
             class="image-item"
             :class="{ active: currentImage?.id === image.id }"
             @click="selectImage(image)">
          <div class="image-actions">
            <button class="delete-btn" @click.stop="confirmDelete(image)">
              <i class="icon">🗑️</i>
            </button>
          </div>
          <img :src="`http://111.229.88.2:8000/uploads/${image.filename}`" 
               :alt="image.filename"
               @error="handleImageError">
          <div class="image-info">
            <span class="filename">{{ getFileName(image.filename) }}</span>
            <span class="person-count" v-if="image.persons">
              {{ image.persons.length }} 人
            </span>
          </div>
        </div>
      </div>

      <!-- 中间和右侧的图片显示区域 -->
      <div class="image-display" v-if="currentImage">
        <!-- 原图 -->
        <div class="image-container original">
          <h3>原始图片</h3>
          <img :src="`http://111.229.88.2:8000/uploads/${currentImage.filename}`" 
               :alt="currentImage.filename"
               @error="handleImageError">
        </div>

        <!-- 标注图 -->
        <div class="image-container annotated" v-if="currentImage.annotated_image">
          <h3>行人检测结果</h3>
          <div class="image-wrapper">
            <img :src="`http://111.229.88.2:8000/uploads/${currentImage.annotated_image}`" 
                 :alt="currentImage.filename"
                 @error="handleImageError">
            <div v-for="person in persons" 
                 :key="person.id" 
                 class="person-box"
                 :style="getPersonStyle(person)"
                 @click="selectPerson(person)">
              <div class="person-label">
                {{ person.id }} ({{ (person.confidence * 100).toFixed(0) }}%)
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 右侧结果显示区域 -->
      <div class="result-area">
        <div v-if="!currentImage" class="placeholder">
          请上传图片进行行人检测
        </div>
        <div v-else-if="loading" class="placeholder">
          正在处理图片...
        </div>
        <div v-else>
          <h3>识别结果</h3>
          <div class="person-list">
            <div v-for="person in persons" 
                 :key="person.id" 
                 class="person-item">
              <div class="person-header">
                <span>行人 {{ person.id }}</span>
                <span class="confidence">置信度: {{ (person.confidence * 100).toFixed(1) }}%</span>
              </div>
              <div class="person-details">
                <p>姿态：{{ person.pose }}</p>
                <p>动作：{{ person.action }}</p>
                <p>服装：{{ person.clothing }}</p>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 添加右侧行人详情 -->
      <div class="person-details" v-if="selectedPerson">
        <h3>行人 {{ selectedPerson.id }}</h3>
        <p>置信度: {{ (selectedPerson.confidence * 100).toFixed(0) }}%</p>
        <p>位置: ({{ selectedPerson.bbox.x.toFixed(1) }}%, {{ selectedPerson.bbox.y.toFixed(1) }}%)</p>
        <p>大小: {{ selectedPerson.bbox.width.toFixed(1) }}% x {{ selectedPerson.bbox.height.toFixed(1) }}%</p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue'
import axios from 'axios'

const fileInput = ref(null)
const imageRef = ref(null)
const imageContainer = ref(null)
const currentImage = ref(null)
const selectedPerson = ref(null)
const images = ref([])
const showAnnotated = ref(true)
const persons = ref([])
const loading = ref(false)

// 触发文件选择
const triggerUpload = () => {
  fileInput.value?.click()
}

// 处理文件选择
const handleFileSelect = async (event) => {
  const files = event.target.files
  if (!files || files.length === 0) return
  
  loading.value = true
  persons.value = [] // 清空之前的结果
  
  try {
    for (const file of files) {
      // 检查文件类型
      if (!file.type.match(/^image\/(jpeg|png)$/)) {
        alert(`文件 ${file.name} 不是支持的格式（仅支持 JPG 和 PNG）`)
        continue
      }

      // 检查文件大小
      if (file.size > 10 * 1024 * 1024) {
        alert(`文件 ${file.name} 超过大小限制（最大10MB）`)
        continue
      }

      const formData = new FormData()
      formData.append('file', file)

      const response = await axios.post('http://111.229.88.2:8000/api/persons/upload', formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
          'Authorization': `Bearer ${localStorage.getItem('token')}`
        }
      })

      if (response.data) {
        // 更新图片列表
        images.value.unshift(response.data)
        
        // 选择最新上传的图片
        currentImage.value = response.data
        
        // 更新检测结果
        if (response.data.persons) {
          persons.value = response.data.persons
        }
        
        // 如果有错误信息，显示警告
        if (response.data.error) {
          alert(`图片 ${file.name} 已上传，但处理过程中出现问题: ${response.data.error}`)
        }
      }
    }
  } catch (error) {
    console.error('上传失败:', error)
    let errorMessage = '上传失败'
    
    if (error.response?.data?.detail) {
      errorMessage = error.response.data.detail
    }
    
    alert(errorMessage)
  } finally {
    loading.value = false
    event.target.value = '' // 清空文件输入框
  }
}

// 选择图片
const selectImage = (image) => {
  console.log('选择图片:', image.filename)
  currentImage.value = image
  persons.value = image.persons || []
  selectedPerson.value = null
}

// 选择行人
const selectPerson = (person) => {
  selectedPerson.value = person
}

// 获取行人框样式
const getPersonStyle = (person) => {
  if (!person.bbox) return {}
  
  return {
    left: `${person.bbox.x}%`,
    top: `${person.bbox.y}%`,
    width: `${person.bbox.width}%`,
    height: `${person.bbox.height}%`,
    border: selectedPerson.value?.id === person.id ? '2px solid #ff4d4f' : '2px solid #52c41a'
  }
}

// 导出数据集
const exportDataset = async () => {
  try {
    const response = await axios.get('http://111.229.88.2:8000/api/persons/export', {
      headers: {
        'Authorization': `Bearer ${localStorage.getItem('token')}`,
        'Accept': 'application/zip'
      },
      responseType: 'blob'
    })
    
    // 创建下载链接
    const url = window.URL.createObjectURL(new Blob([response.data]))
    const link = document.createElement('a')
    link.href = url
    const filename = response.headers['content-disposition']?.split('filename=')[1] || 'person_detection_dataset.zip'
    link.setAttribute('download', filename)
    document.body.appendChild(link)
    link.click()
    link.remove()
    window.URL.revokeObjectURL(url)
  } catch (error) {
    console.error('导出失败:', error)
    alert(error.response?.data?.detail || '导出失败')
  }
}

// 获取图片列表
const fetchImages = async () => {
  try {
    const response = await axios.get('http://111.229.88.2:8000/api/persons', {
      headers: {
        'Authorization': `Bearer ${localStorage.getItem('token')}`
      }
    })
    images.value = response.data
  } catch (error) {
    console.error('获取图片列表失败:', error)
    alert(error.response?.data?.detail || '获取图片列表失败')
  }
}

// 获取文件名（去掉路径）
const getFileName = (filename) => {
  return filename.split('/').pop()
}

// 获取当前显示的图片路径
const getImagePath = () => {
  if (currentImage.value) {
    if (showAnnotated.value && currentImage.value.annotated_image) {
      console.log('显示标注图:', currentImage.value.annotated_image)
      return currentImage.value.annotated_image
    }
    console.log('显示原图:', currentImage.value.filename)
    return currentImage.value.filename
  }
  return ''
}

// 切换原图/标注图
const toggleAnnotation = () => {
  showAnnotated.value = !showAnnotated.value
  console.log('切换显示:', showAnnotated.value ? '标注图' : '原图')
}

// 处理图片加载
const handleImageLoad = () => {
  console.log('图片加载完成:', getImagePath())
}

// 处理图片加载错误
const handleImageError = (event) => {
  console.error('图片加载失败:', event.target.src)
}

// 确认删除图片
const confirmDelete = async (image) => {
  if (confirm('确定要删除这张图片吗？')) {
    try {
      await axios.delete(`/api/persons/${image.id}`, {
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token')}`
        }
      })
      
      // 从列表中移除
      images.value = images.value.filter(img => img.id !== image.id)
      
      // 如果删除的是当前选中的图片，清空选择
      if (currentImage.value?.id === image.id) {
        currentImage.value = null
        persons.value = []
        selectedPerson.value = null
      }
      
    } catch (error) {
      console.error('删除失败:', error)
      alert(error.response?.data?.detail || '删除失败')
    }
  }
}

// 修改图片URL获取逻辑
const getImageUrl = (image) => {
  if (showAnnotated.value && image.annotated_image) {
    return `http://111.229.88.2:8000/uploads/${image.annotated_image}`
  }
  return `http://111.229.88.2:8000/uploads/${image.filename}`
}

onMounted(() => {
  fetchImages()
})
</script>

<style scoped>
.person-recognition {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.toolbar {
  margin-bottom: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
}

.left-actions,
.right-actions {
  display: flex;
  gap: 12px;
}

.upload-btn,
.export-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
}

.upload-btn {
  background-color: #1890ff;
}

.upload-btn:hover {
  background-color: #096dd9;
}

.export-btn {
  background-color: #52c41a;
}

.export-btn:hover {
  background-color: #389e0d;
}

.icon {
  font-size: 18px;
}

.content-area {
  flex: 1;
  display: grid;
  grid-template-columns: 200px 1fr 300px;
  gap: 20px;
  background: white;
  border-radius: 8px;
  overflow: hidden;
}

.images-list {
  width: 200px;
  padding: 20px;
  border-right: 1px solid #e8e8e8;
  overflow-y: auto;
}

.image-item {
  position: relative;
  margin-bottom: 16px;
  border: 1px solid #e8e8e8;
  border-radius: 4px;
  overflow: hidden;
}

.image-actions {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
  display: none;
}

.image-item:hover .image-actions {
  display: block;
}

.delete-btn {
  background: rgba(255, 0, 0, 0.7);
  color: white;
  border: none;
  border-radius: 4px;
  padding: 4px 8px;
  cursor: pointer;
  transition: all 0.3s;
}

.delete-btn:hover {
  background: rgba(255, 0, 0, 0.9);
}

.image-item img {
  width: 100%;
  height: 120px;
  object-fit: cover;
  display: block;
}

.image-info {
  padding: 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.person-count {
  background: #1890ff;
  color: white;
  padding: 2px 6px;
  border-radius: 10px;
  font-size: 12px;
}

.image-display {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  padding: 20px;
  overflow: auto;
}

.image-container {
  flex: 1;
  min-width: 0;
  padding: 10px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.image-container h3 {
  margin: 0 0 16px 0;
  color: #1890ff;
  font-size: 16px;
}

.image-container img {
  max-width: 100%;
  height: auto;
  display: block;
  border-radius: 4px;
}

.image-item.active {
  border-color: #1890ff;
}

.image-item img {
  width: 100%;
  height: auto;
  display: block;
}

.image-info {
  padding: 8px;
  background: rgba(0, 0, 0, 0.03);
}

.filename {
  font-size: 12px;
  color: #666;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.person-count {
  font-size: 12px;
  color: #1890ff;
  margin-top: 4px;
  display: inline-block;
}

.result-area {
  padding: 20px;
  background: #f8f8f8;
  border-left: 1px solid #e8e8e8;
}

.placeholder {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #999;
}

.person-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.person-item {
  background: white;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.person-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid #f0f0f0;
}

.person-details {
  padding: 16px;
  background: #f8f8f8;
  border-radius: 4px;
  margin-top: 16px;
}

.person-details h3 {
  margin: 0 0 12px 0;
  color: #1890ff;
}

.person-item.active {
  border: 1px solid #1890ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

.confidence {
  background: rgba(0, 0, 0, 0.2);
  padding: 0 4px;
  border-radius: 2px;
}

.image-controls {
  margin-top: 16px;
  text-align: center;
}

.image-controls button {
  padding: 8px 16px;
  background: #1890ff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
  font-size: 14px;
}

.image-controls button:hover {
  background: #40a9ff;
}

.image-wrapper {
  position: relative;
  display: inline-block;
  max-width: 100%;
}

.image-wrapper img {
  max-width: 100%;
  height: auto;
  display: block;
}

.person-box {
  position: absolute;
  border: 2px solid #52c41a;
  cursor: pointer;
  transition: all 0.3s;
  box-sizing: border-box;
  pointer-events: all;
}

.person-box:hover {
  border-color: #ff4d4f;
  border-width: 3px;
}

.person-label {
  position: absolute;
  top: -25px;
  left: 0;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 2px 6px;
  border-radius: 2px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1;
}

.image-container {
  position: relative;
  flex: 1;
  min-width: 0;
  padding: 10px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
</style> 